#include "TCPClient.hpp"

// 构造函数
TCPClient::TCPClient(const std::string &serverIP, int serverPort)
    : m_serverIP(serverIP),
      m_serverPort(serverPort),
      m_clientSocket(INVALID_SOCKET),
      m_isRunning(false),
      m_isConnected(false),
      m_receiveRunning(false)
{
}

// 析构函数
TCPClient::~TCPClient()
{
    stopConnection();
}

// 初始化函数
bool TCPClient::initialize()
{
    WSADATA wsaData;
    if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
    {
        std::cerr << "WSAStartup failed." << std::endl;
        return false;
    }
    return true;
}

// 连接服务器函数
bool TCPClient::connectToServer()
{
    // 获取锁
    std::lock_guard<std::mutex> lock(m_socketMutex);

    // 如果已经连接，先关闭
    if (m_clientSocket != INVALID_SOCKET)
    {
        closesocket(m_clientSocket);
    }

    // 创建socket
    m_clientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (m_clientSocket == INVALID_SOCKET)
    {
        std::cerr << "Error creating socket: " << WSAGetLastError() << std::endl;
        return false;
    }

    // 设置服务器地址
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(m_serverPort);
    inet_pton(AF_INET, m_serverIP.c_str(), &serverAddr.sin_addr);

    std::cout << "Attempt to connect" << std::endl;
    // 尝试连接
    if (connect(m_clientSocket, (sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
    {
        std::cerr << "Connect failed: " << WSAGetLastError() << std::endl;
        closesocket(m_clientSocket);
        m_clientSocket = INVALID_SOCKET;
        m_isConnected = false;
        return false;
    }

    // 连接成功
    m_isConnected = true;
    std::cout << "Connected to server " << m_serverIP << ":" << m_serverPort << std::endl;
    // 启动接收线程
    m_receiveRunning = true;
    m_receiveThread = std::thread(&TCPClient::receiveDataInThread, this);
    m_receiveThread.detach();
    return true;
}

// 启动连接线程函数
void TCPClient::startConnection()
{
    if (m_isRunning)
        return;

    initialize();
    m_isRunning = true;
    m_reconnectThread = std::thread(&TCPClient::reconnectThread, this);
    m_reconnectThread.detach(); // 分离线程
}

// 重新连接线程函数
void TCPClient::reconnectThread()
{
    // 每1秒循环尝试连接
    while (m_isRunning)
    {
        if (!m_isConnected)
        {
            connectToServer();
        }
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

// 停止连接函数
void TCPClient::stopConnection()
{
    m_isRunning = false;      // 停止重连
    m_receiveRunning = false; // 停止接收

    // 等待线程结束
    if (m_reconnectThread.joinable())
    {
        m_reconnectThread.join();
    }

    if (m_receiveThread.joinable())
    {
        m_receiveThread.join();
    }

    // 关闭socket
    if (m_clientSocket != INVALID_SOCKET)
    {
        closesocket(m_clientSocket);
        m_clientSocket = INVALID_SOCKET;
    }

    // 清理WSA
    WSACleanup();
}

// 发送数据函数
bool TCPClient::sendData(const std::string &data)
{
    std::cout << "Send data: " << data << std::endl;

    // 检查连接状态
    if (!m_isConnected || m_clientSocket == INVALID_SOCKET)
    {
        std::cout << "Not connected to server" << std::endl;
        return false;
    }
    // 发送数据
    int result = send(m_clientSocket, data.c_str(), data.length(), 0);
    if (result == SOCKET_ERROR)
    {
        std::cerr << "Send failed: " << WSAGetLastError() << std::endl;
        m_isConnected = true;
        return false;
    }
    std::cout << "Send data success" << std::endl;

    return true;
}

// 接收数据函数
std::string TCPClient::receiveData()
{
    std::lock_guard<std::mutex> lock(m_socketMutex);

    if (!m_isConnected || m_clientSocket == INVALID_SOCKET)
    {
        return "";
    }

    char buffer[1024] = {0};
    int bytesReceived = recv(m_clientSocket, buffer, sizeof(buffer) - 1, 0);

    if (bytesReceived > 0)
    {
        buffer[bytesReceived] = '\0'; // 确保字符串以空字符结尾
        return std::string(buffer);
    }
    else if (bytesReceived == 0) // 服务器关闭了连接
    {
        std::cout << "Connection closed by server" << std::endl;
        m_isConnected = false;
    }
    else // 接收失败
    {
        std::cerr << "Receive failed: " << WSAGetLastError() << std::endl;
        m_isConnected = false;
    }

    return "";
}

// 接收数据线程函数
void TCPClient::receiveDataInThread()
{
    while (m_receiveRunning)
    {
        std::string message = receiveData();
        if (!message.empty())
        {
            // 处理接收到的消息
            std::cout << "Received message: " << message << std::endl;
        }
    }
}

// 获取连接状态函数
bool TCPClient::isConnected() const
{
    return m_isConnected;
}
